import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { config } from './config';
import { logger } from '../utils/logger';
import { CLIError, User, Project, Module, Environment, Secret, VersionInfo } from '../types';

class ApiService {
  private client: AxiosInstance;

  constructor() {
    this.client = axios.create({
      baseURL: config.getApiUrl(),
      timeout: 30000,
      headers: {
        'Content-Type': 'application/json',
      }
    });

    this.client.interceptors.request.use((requestConfig) => {
      const token = config.getToken();
      if (token) {
        requestConfig.headers.Authorization = `Bearer ${token}`;
      }
      
      // 调试日志：记录请求详情
      logger.debug(`API Request: ${requestConfig.method?.toUpperCase()} ${this.client.defaults.baseURL}${requestConfig.url}`, {
        headers: requestConfig.headers,
        data: requestConfig.data
      });
      
      return requestConfig;
    });

    this.client.interceptors.response.use(
      (response) => {
        logger.debug(`API Response: ${response.status} ${response.statusText}`, {
          data: response.data
        });
        return response;
      },
      (error) => {
        logger.debug('API Error', {
          status: error.response?.status,
          statusText: error.response?.statusText,
          data: error.response?.data,
          message: error.message,
          url: error.config?.url
        });
        
        const cliError = new CLIError(
          error.response?.data?.message || error.message,
          error.response?.data?.code || 'API_ERROR',
          error.response?.status
        );
        throw cliError;
      }
    );
  }

  private async request<T>(config: AxiosRequestConfig): Promise<T> {
    const response: AxiosResponse<T> = await this.client.request(config);
    return response.data;
  }

  async login(email: string, password: string): Promise<{ token: string; user: User }> {
    return this.request({
      method: 'POST',
      url: '/auth/login',
      data: { email, password }
    });
  }

  async sendSmsCode(phone: string): Promise<void> {
    return this.request({
      method: 'POST',
      url: '/lowcode-user/api/user/sendCode',
      data: { phone }
    });
  }

  async sendEmailCode(email: string): Promise<void> {
    return this.request({
      method: 'POST',
      url: '/lowcode-user/api/user/sendEmailCode',
      data: { email }
    });
  }

  async codeLogin(phone: string, code: string): Promise<{ token: string; user: User }> {
    return this.request({
      method: 'POST',
      url: '/lowcode-user/api/user/code/login',
      data: { phone, code }
    });
  }

  async emailCodeLogin(email: string, code: string): Promise<{ token: string; user: User }> {
    return this.request({
      method: 'POST',
      url: '/lowcode-user/api/user/email/code/login',
      data: { email, code }
    });
  }

  async getMe(): Promise<User> {
    return this.request({
      method: 'GET',
      url: '/auth/me'
    });
  }

  async getProjects(): Promise<Project[]> {
    return this.request({
      method: 'GET',
      url: '/projects'
    });
  }

  async createProject(name: string, description?: string): Promise<Project> {
    return this.request({
      method: 'POST',
      url: '/projects',
      data: { name, description }
    });
  }

  async getProject(id: string): Promise<Project> {
    return this.request({
      method: 'GET',
      url: `/projects/${id}`
    });
  }

  async createEnvironment(projectId: string, name: string, type: Environment['type']): Promise<Environment> {
    return this.request({
      method: 'POST',
      url: `/projects/${projectId}/environments`,
      data: { name, type }
    });
  }

  async getEnvironments(projectId: string): Promise<Environment[]> {
    return this.request({
      method: 'GET',
      url: `/projects/${projectId}/environments`
    });
  }

  async searchModules(query: string): Promise<Module[]> {
    return this.request({
      method: 'GET',
      url: '/modules/search',
      params: { q: query }
    });
  }

  async getModule(id: string): Promise<Module> {
    return this.request({
      method: 'GET',
      url: `/modules/${id}`
    });
  }

  async installModule(projectId: string, environmentId: string, moduleId: string, version?: string): Promise<void> {
    return this.request({
      method: 'POST',
      url: `/projects/${projectId}/environments/${environmentId}/modules`,
      data: { moduleId, version }
    });
  }

  async removeModule(projectId: string, environmentId: string, moduleId: string): Promise<void> {
    return this.request({
      method: 'DELETE',
      url: `/projects/${projectId}/environments/${environmentId}/modules/${moduleId}`
    });
  }

  async getSecrets(projectId: string, environmentId: string): Promise<Secret[]> {
    return this.request({
      method: 'GET',
      url: `/projects/${projectId}/environments/${environmentId}/secrets`
    });
  }

  async setSecret(projectId: string, environmentId: string, key: string, value: string): Promise<void> {
    return this.request({
      method: 'PUT',
      url: `/projects/${projectId}/environments/${environmentId}/secrets/${key}`,
      data: { value }
    });
  }

  async deleteSecret(projectId: string, environmentId: string, key: string): Promise<void> {
    return this.request({
      method: 'DELETE',
      url: `/projects/${projectId}/environments/${environmentId}/secrets/${key}`
    });
  }

  async callModuleAction(projectId: string, environmentId: string, moduleId: string, action: string, input: any): Promise<any> {
    return this.request({
      method: 'POST',
      url: `/projects/${projectId}/environments/${environmentId}/modules/${moduleId}/actions/${action}`,
      data: { input }
    });
  }

  async getModuleLogs(projectId: string, environmentId: string, moduleId: string): Promise<string[]> {
    return this.request({
      method: 'GET',
      url: `/projects/${projectId}/environments/${environmentId}/modules/${moduleId}/logs`
    });
  }

  async publishModule(moduleId: string, version: string, tag?: string): Promise<void> {
    return this.request({
      method: 'POST',
      url: `/modules/${moduleId}/versions`,
      data: { version, tag }
    });
  }

  async getModuleVersions(moduleId: string): Promise<VersionInfo[]> {
    return this.request({
      method: 'GET',
      url: `/modules/${moduleId}/versions`
    });
  }

  async promoteVersion(moduleId: string, fromTag: string, toTag: string): Promise<void> {
    return this.request({
      method: 'POST',
      url: `/modules/${moduleId}/promote`,
      data: { fromTag, toTag }
    });
  }
}

export const api = new ApiService();